/**
 Copyright (C) 2013 Yuyao Liang

 This source code is release under the BSD License.

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.

 Created on Nov 25, 2013 4:01:05 PM
 */
package com.googlecode.backtest.dataset.manager;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.googlecode.backtest.controller.ConstructorArguments;
import com.googlecode.backtest.controller.IBackTestController;
import com.googlecode.backtest.controller.IConstructorArguments;
import com.googlecode.backtest.document.IBackTestContent;
import com.googlecode.backtest.document.Item;
import com.googlecode.backtest.rule.ISourceAlgorithm;
import com.googlecode.backtest.rule.ta.TAParameters;

/**
 * @author lianyuy
 * 
 */
@SuppressWarnings("rawtypes")
public class BackTestDataManager extends DataManager {
	protected List<String> keys = new ArrayList<String>();
	protected IBackTestController controller;

	public BackTestDataManager(IBackTestController controller) {
		super();
		this.controller = controller;
	}

	/**
	 * @param keys
	 */
	public BackTestDataManager(List<String> keys) {
		super();
		this.keys = keys;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.googlecode.backtest.document.DataManager#putData(java.lang.String,
	 * java.lang.Object)
	 */
	@Override
	public void putData(String key, Object data) {
		if (!keys.contains(key)) {
			keys.add(key);
		}

		super.putData(key, data);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.googlecode.backtest.dataset.manager.IDataManager#parseContent(com
	 * .googlecode.backtest.document.IBackTestContent)
	 */
	@Override
	public void parseContent(IBackTestContent<Item> content) {
		Iterator<Item> iterator = content.getIterator();
		while (iterator.hasNext()) {
			Item item = iterator.next();
			parseItem(item);
		}
	}

	/**
	 * @param item
	 * @throws ClassNotFoundException
	 */
	private void parseItem(Item item) {
		Iterator<Item> iterator = item.getIterator();
		if (iterator != null) {
			while (iterator.hasNext()) {
				Item it = iterator.next();
				parseItem(it);
			}
		}

		try {
			IConstructorArguments arguments = new ConstructorArguments(
					item.getItemID());
			Class algclass = Class.forName(item.getClassName());
			TAParameters param = (TAParameters) item.getParam();
			List<String> dataids = item.getSourceIDs();

			Constructor[] cs = algclass.getConstructors();
			Object[] args = new Object[] { arguments.getGUID(), dataids, param };
			Object instance = cs[0].newInstance(args);

			if (instance instanceof DataReadyEventListener) {
				DataReadyEventListener listener = (DataReadyEventListener) instance;
				Iterator<String> iditer = item.getSourceIDIterator();
				while (iditer.hasNext()) {
					String id = iditer.next();
					this.register(id, listener);
				}
			}
			if (instance instanceof ISourceAlgorithm) {
				ISourceAlgorithm source = (ISourceAlgorithm) instance;
				sourcelist.add(source);
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}

}
